﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace BaseKnowledge
{
    /// <summary>
    /// Channel的使用
    /// 参考： https://learn.microsoft.com/en-us/dotnet/core/extensions/channels#unbounded-creation-patterns
    /// </summary>
    public class ChannelDemo
    {
        public static Channel<string> unBoundMessageChannel = Channel.CreateUnbounded<string>();
        public static Channel<int> boundMessageChannel = Channel.CreateBounded<int>(
            new BoundedChannelOptions(10)
            {
                SingleWriter = true,
                SingleReader = false,
                // 开启多消费者，多生产者
                AllowSynchronousContinuations = true,
                FullMode = BoundedChannelFullMode.Wait
            });
        public void CreateUnBoundMessage()
        {

            for (int z = 0; z < 100; z++)
            {
                Thread.Sleep(10);
                unBoundMessageChannel.Writer.TryWrite(z.ToString());
            }
            unBoundMessageChannel.Writer.TryComplete();
        }

        // 必须使用异步，解放生产力，这样才能一边生产，一边消费
        public async void CreateBoundMessage()
        {
            int i = 10;
            while (i != 100 && await boundMessageChannel.Writer.WaitToWriteAsync())
            {
                Thread.Sleep(10);
                Random random = new Random();
                var num = random.Next(1, 200);
                await boundMessageChannel.Writer.WriteAsync(num);
            }
            boundMessageChannel.Writer.TryComplete();
            Console.WriteLine("消息已经写结束" + boundMessageChannel.Reader.Count);
        }

        public void ConsumeUnBoundMessage()
        {
            Task.Run(() =>
            {
                while (unBoundMessageChannel.Reader.TryRead(out string msg))
                {
                    var threadStr = Thread.CurrentThread.ManagedThreadId.ToString();
                    Console.WriteLine($"线程{threadStr}读取无线消息(B)通道：{msg}");
                }
            });
        }

        public async void ConsumeBoundMessage()
        {
            await Task.Run(async
                () =>
            {
                var threadStr = Thread.CurrentThread.ManagedThreadId.ToString();
                while (await boundMessageChannel.Reader.WaitToReadAsync())
                {
                    while (boundMessageChannel.Reader.TryRead(out int msg))
                    {
                        Thread.Sleep(100);
                        Console.WriteLine($"线程{threadStr}读取有限线消息(A)通道：{msg}");
                    }
                }
            });
        }


    }
}
